﻿#Include ..\_lib\Extend.ahk

; 将字符串按字母顺序排序，并分组
groupAndSortStrings(str, splitCh) {

  Sort(str, 'D' splitCh)
  grouped := {}, arr := str.split(splitCh)

  for v in arr {
    firstLetter := v[1].toUpperCase()
    if !grouped[firstLetter]
      grouped[firstLetter] := []
    grouped[firstLetter].push(v)
  }

  result := []
  for letter in grouped.OwnProps() {
    result.push({ letter: letter, words: grouped[letter] })
  }

  return result
}

; 将一个字符串裁剪为每部分字符不超过 l 的新串
; 如：
; slice('012345678', 4)
; => 0123
;    4567
;    8
;
; 如果字符串本身带有换行符，则优先换行并重新计数
; 如：
; slice('012`n345678', 4)
; => 012
;    3456
;    78
;
; 使用参数 n 定义折行连接符
slice(t, l, n := '`n') {
  return StrSplit(t, '`n').reduce((acc, cur) => acc . _c(cur, 1), '').RTrim(n)

  _c(v, i) => _t(v) - i < l ? SubStr(v, i) '`n' : SubStr(v, i, _l := _s(v, i)) n _c(v, i + _l)
  ; 统计 str 的长度，汉字与全角计为 2
  _t(str) => str.toCharArray().reduce((acc, cur) => acc += (IsHan(cur) || IsFullChar(cur)) ? 2 : 1, 0)
  ; 获取下一个裁剪的起始下标
  _s(v, i) => Max(1, _t(a := SubStr(v, i, l)) <= l ? l : (j := 0, Array.from(a).findIndex(c => (j += (IsHan(c) || IsFullChar(c)) ? 2 : 1) >= l) - (j > l)))
}


; Usage:
; ```
;     AppendSuffix := (str) => str .= 'ed'
;     CachedAppendSuffix := CacheFunc(AppendSuffix)
;     test := 'foo'
;     MsgBox CachedAppendSuffix(test)
;     MsgBox CachedAppendSuffix(test)
; ```
CacheFunc(fn) {
  _cache := {}
  cachedFn(param*) {
    key := ToString(param)
    hit := _cache[key]
    return hit || (_cache[key] := fn(param*))
  }
  return cachedFn
}

; strs := ['flow', 'flower', 'fl', '.']
; MToString longestCommonPrefix(strs)
longestCommonPrefix(strs) {
  if !strs.length
    return

  prefix := strs[1]

  loop strs.length - 1 {
    i := A_Index + 1
    while !beginWith(strs[i], prefix) {
      prefix := SubStr(prefix, 1, prefix.length - 1)
      if prefix = ''
        return ''
    }
  }
  return prefix
}

; . 被当作通配符
beginWith(str, t) {
  if t.length > str.length
    return false
  if t = str
    return true
  a := str.substring(1, t.length + 1).toChs()
  b := t.toChs()
  return b.every((v, i) => (v = a[i] || a[i] = '.' || v = '.')) ; 使用 == 可区分大小写
}


generateColor() {
  hue := floor(random() * 360) ; 生成一个随机的色相值（0到360之间）
    , saturation := floor(random() * 51) + 50  ; 饱和度设为随机值，保持在50%到100%之间
    , lightness := floor(random() * 21) + 50 ; 亮度设为50%到70%之间，避免过亮或过暗
  return hslToHex(hue, saturation, lightness) ; 将HSL转换为hex格式
}

; HSL转HEX的函数
hslToHex(h, s, l) {
  s /= 100, l /= 100
  c := (1 - abs(2 * l - 1)) * s, x := c * (1 - abs(Mod(h / 60, 2) - 1)), m := l - c / 2

  if (h >= 0 && h < 60) {
    r := c, g := x, b := 0
  } else if (h >= 60 && h < 120) {
    r := x, g := c, b := 0
  } else if (h >= 120 && h < 180) {
    r := 0, g := c, b := x
  } else if (h >= 180 && h < 240) {
    r := 0, g := x, b := c
  } else if (h >= 240 && h < 300) {
    r := x, g := 0, b := c
  } else {
    r := c, g := 0, b := x
  }

  r := round((r + m) * 255), g := round((g + m) * 255), b := round((b + m) * 255)
  return toHex(r) toHex(g) toHex(b)

  toHex(n) {
    hex := n.toBase(16)
    return hex.length = 1 ? '0' hex : hex
  }
}

TruncatedString(text, maxLen) => text.Length > maxLen ? (text.substring(1, maxLen) '...') : text